const countDecimals = function (num: number | string) {
  let len = 0;
  try {
    num = Number(num);
    let str = num.toString().toUpperCase();
    if (str.split("E").length === 2) {
      let isDecimal = false;
      if (str.split(".").length === 2) {
        str = str.split(".")[1];
        if (parseInt(str.split("E")[0]) !== 0) {
          isDecimal = true;
        }
      }
      let x = str.split("E");
      if (isDecimal) {
        len = x[0].length;
      }
      len -= parseInt(x[1]);
    } else if (str.split(".").length === 2) {
      if (parseInt(str.split(".")[1]) !== 0) {
        len = str.split(".")[1].length;
      }
    }
  } catch (e) {
    throw e;
  } finally {
    if (isNaN(len) || len < 0) {
      len = 0;
    }
    return len;
  }
};

const convertToInt = function (num: number | string) {
  num = Number(num);
  let newNum = num;
  let times = countDecimals(num);
  let temp_num = num.toString().toUpperCase();
  if (temp_num.split("E").length === 2) {
    newNum = Math.round(num * Math.pow(10, times));
  } else {
    newNum = Number(temp_num.replace(".", ""));
  }
  return newNum;
};

const getCorrectResult = function (
  type: string,
  num1: number,
  num2: number,
  result: number
) {
  let temp_result = 0;
  switch (type) {
    case "add":
      temp_result = num1 + num2;
      break;
    case "sub":
      temp_result = num1 - num2;
      break;
    case "div":
      temp_result = num1 / num2;
      break;
    case "mul":
      temp_result = num1 * num2;
      break;
  }
  if (Math.abs(result - temp_result) > 1) {
    return temp_result;
  }
  return result;
};

//加法
export const accAdd = (num1: number, num2: number) => {
  num1 = Number(num1);
  num2 = Number(num2);
  let dec1, dec2, times;
  try {
    dec1 = countDecimals(num1) + 1;
  } catch (e) {
    dec1 = 0;
  }
  try {
    dec2 = countDecimals(num2) + 1;
  } catch (e) {
    dec2 = 0;
  }
  times = Math.pow(10, Math.max(dec1, dec2));
  let result = (accMul(num1, times) + accMul(num2, times)) / times;
  return getCorrectResult("add", num1, num2, result);
};

//减法
export const accSub = (num1: number, num2: number) => {
  num1 = Number(num1);
  num2 = Number(num2);
  let dec1, dec2, times;
  try {
    dec1 = countDecimals(num1) + 1;
  } catch (e) {
    dec1 = 0;
  }
  try {
    dec2 = countDecimals(num2) + 1;
  } catch (e) {
    dec2 = 0;
  }
  times = Math.pow(10, Math.max(dec1, dec2));
  let result = Number(
    (accMul(num1, times) - accMul(num2, times)) / times
  );
  return getCorrectResult("sub", num1, num2, result);
};

//除法
export const accDiv = (num1: number, num2: number) => {
  num1 = Number(num1);
  num2 = Number(num2);
  let t1 = 0,
    t2 = 0,
    dec1,
    dec2;
  try {
    t1 = countDecimals(num1);
  } catch (e) {}
  try {
    t2 = countDecimals(num2);
  } catch (e) {}
  dec1 = convertToInt(num1);
  dec2 = convertToInt(num2);
  let result = accMul(dec1 / dec2, Math.pow(10, t2 - t1));
  return getCorrectResult("div", num1, num2, result);
};

//乘法
export const accMul = (num1: number, num2: number) => {
  num1 = Number(num1);
  num2 = Number(num2);
  let times = 0,
    s1 = num1.toString(),
    s2 = num2.toString();
  try {
    times += countDecimals(s1);
  } catch (e) {}
  try {
    times += countDecimals(s2);
  } catch (e) {}
  let result = (convertToInt(s1) * convertToInt(s2)) / Math.pow(10, times);
  return getCorrectResult("mul", num1, num2, result);
};

/**
 * @description: 比较版本号大小
 * @param {any} v1
 * @param {any} v2
 * @return {*} 0 相等 -1 老版本  1 新版本
 */
export const compare = (v1: any, v2: any) => {
  if (v1 === v2) {
      return 0
  }
  const arr1 = v1.split(/\D/)
  const arr2 = v2.split(/\D/)

  // 默认版本号长度一样
  for (let i = 0; i < arr1.length;) {
    // 字符串相减将字符串隐式转成数字
    if (arr1[i] - arr2[i] > 0){
        return 1
    }
    if (arr1[i] - arr2[i] < 0) {
        return -1
    }
    if (arr1[i] === arr2[i]) {
        i ++
    }
  }
};
